type RGB = {
  r: number;
  g: number;
  b: number;
};

const rgbWhite = {
  r: 255,
  g: 255,
  b: 255
};
const rgbBlack = {
  r: 0,
  g: 0,
  b: 0
};

// 将一个数字转换为16进制字符串
function componentToHex(c: number): string {
  const hex = Math.round(c).toString(16);
  return hex.length === 1 ? "0" + hex : hex;
}

// 将RGB颜色转换为十六进制颜色
function rgbToHex(rgb: RGB): string {
  return `#${componentToHex(rgb.r)}${componentToHex(rgb.g)}${componentToHex(rgb.b)}`;
}

// 定义一个函数mix，用于混合两种颜色
function mix(color: RGB, mixColor: RGB, weight: number): RGB {
  return {
    r: color.r * (1 - weight) + mixColor.r * weight,
    g: color.g * (1 - weight) + mixColor.g * weight,
    b: color.b * (1 - weight) + mixColor.b * weight
  };
}

/**
 * 将任意合法的颜色格式转换为 RGB 对象
 * 支持：#FF0000 / rgb(255,0,0) / hsl(0,100%,50%) / hsv(0,100%,100%)
 */
function colorToRGB(color: string): RGB {
  // 去除空格
  const c = color.trim();

  // 处理 HEX 格式
  if (c.startsWith("#")) {
    let hex = c.replace("#", "");
    if (hex.length === 3 || hex.length === 4) {
      // 简写 #RGB 或 #RGBA
      hex = hex
        .split("")
        .map(ch => ch + ch)
        .join("");
    }
    if (hex.length >= 6) {
      return {
        r: parseInt(hex.slice(0, 2), 16),
        g: parseInt(hex.slice(2, 4), 16),
        b: parseInt(hex.slice(4, 6), 16)
      };
    }
  }

  // 处理 RGB / RGBA 格式
  const rgbMatch = c.match(/rgb$$(\d+),\s*(\d+),\s*(\d+)(?:,\s*[\d.]+)?$$/i);
  if (rgbMatch) {
    return {
      r: parseInt(rgbMatch[1], 10),
      g: parseInt(rgbMatch[2], 10),
      b: parseInt(rgbMatch[3], 10)
    };
  }

  // 处理 HSL 格式
  const hslMatch = c.match(/hsl$$(\d+),\s*(\d+)%,\s*(\d+)%(?:,\s*[\d.]+)?$$/i);
  if (hslMatch) {
    const h = parseInt(hslMatch[1]);
    const s = parseInt(hslMatch[2]);
    const l = parseInt(hslMatch[3]);
    return hslToRgb(h, s, l);
  }

  // 处理 HSV/HSB 格式
  const hsvMatch = c.match(/hsv$$(\d+),\s*(\d+)%,\s*(\d+)%(?:,\s*[\d.]+)?$$/i);
  if (hsvMatch) {
    const h = parseInt(hsvMatch[1]);
    const s = parseInt(hsvMatch[2]);
    const v = parseInt(hsvMatch[3]);
    return hsvToRgb(h, s, v);
  }

  throw new Error(`不支持的颜色格式: ${color}`);
}

// HSL -> RGB
function hslToRgb(h: number, s: number, l: number): RGB {
  s /= 100;
  l /= 100;

  const k = n => (n + h / 30) % 12;
  const a = s * Math.min(l, 1 - l);
  const f = n => l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));

  return {
    r: Math.round(f(0) * 255),
    g: Math.round(f(8) * 255),
    b: Math.round(f(4) * 255)
  };
}

// HSV -> RGB
function hsvToRgb(h: number, s: number, v: number): RGB {
  s /= 100;
  v /= 100;

  const i = Math.floor(h / 60) % 6;
  const f = h / 60 - i;
  const p = v * (1 - s);
  const q = v * (1 - f * s);
  const t = v * (1 - (1 - f) * s);

  const [r, g, b] = [
    [v, t, p],
    [q, v, p],
    [p, v, t],
    [p, q, v],
    [t, p, v],
    [v, p, q]
  ][i];

  return {
    r: Math.round(r * 255),
    g: Math.round(g * 255),
    b: Math.round(b * 255)
  };
}

/**
 * 修改 element-plus的颜色主题
 */
function updateElementPlusTheme(type: string, baseColor: string): void {
  // 针对 element-plus 进行修改
  const colorArray: Record<string, string>[] = [
    { className: `--el-color-${type}`, color: rgbToHex(mix(colorToRGB(baseColor), rgbBlack, 0)) },
    { className: `--el-color-${type}-dark-2`, color: rgbToHex(mix(colorToRGB(baseColor), rgbBlack, 0.2)) },
    { className: `--el-color-${type}-light-3`, color: rgbToHex(mix(colorToRGB(baseColor), rgbWhite, 0.3)) },
    { className: `--el-color-${type}-light-5`, color: rgbToHex(mix(colorToRGB(baseColor), rgbWhite, 0.5)) },
    { className: `--el-color-${type}-light-7`, color: rgbToHex(mix(colorToRGB(baseColor), rgbWhite, 0.7)) },
    { className: `--el-color-${type}-light-8`, color: rgbToHex(mix(colorToRGB(baseColor), rgbWhite, 0.78)) },
    { className: `--el-color-${type}-light-9`, color: rgbToHex(mix(colorToRGB(baseColor), rgbWhite, 0.85)) }
  ];

  colorArray.forEach(item => {
    document.documentElement.style.setProperty(item.className, item.color);
  });
}
export type { RGB };

export { colorToRGB, rgbToHex, updateElementPlusTheme };
